package com.ohos.connect.devicecloud.mqtt.modular.mqtt.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ohos.connect.devicecloud.mqtt.core.config.MqttClientInit;
import com.ohos.connect.devicecloud.mqtt.core.model.vo.MqttAccountVO;
import com.ohos.connect.devicecloud.mqtt.modular.mqtt.enums.MqttLoginStatusEnum;
import com.ohos.connect.devicecloud.mqtt.modular.mqtt.model.dto.MqttLoginDTO;
import com.ohos.connect.devicecloud.mqtt.modular.mqtt.service.MqttService;
import org.eclipse.paho.mqttv5.client.MqttClient;
import org.eclipse.paho.mqttv5.common.MqttException;
import org.eclipse.paho.mqttv5.common.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class MqttServiceImpl implements MqttService {

    private static final Logger log = LoggerFactory.getLogger(MqttServiceImpl.class);
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private MqttClientInit mqttClientInit;

    @Value("${mqtt.broker}")
    private String mqttUrl;

    @Override
    public ResponseEntity<Map<String,Object>> mqttLoginAuth(MqttLoginDTO mqttLoginDTO) {
        MqttLoginStatusEnum checkResult = checkMqttAccountByRedis(mqttLoginDTO);
        Map<String, Object> responseBody = constructMqttAuthResult(checkResult);
        return ResponseEntity.ok()
                .header("Content-Type", "application/json")
                .body(responseBody);
    }

    @Override
    public MqttClient getMqttClient() {
        return mqttClientInit.getMqttClient();
    }

    @Override
    public void sendMqttMessage(String topic, MqttMessage mqttMessage) throws MqttException {
        log.info("MQTT publish topic:{}, message:{}", topic, mqttMessage);
        MqttClient mqttClient = mqttClientInit.getMqttClient();
        mqttMessage.setQos(1);
        mqttClient.publish(topic,mqttMessage);
    }

    private MqttLoginStatusEnum checkMqttAccountByRedis(MqttLoginDTO mqttLoginDTO){
        String clientId = mqttLoginDTO.getClientId();
        String username = mqttLoginDTO.getUsername();
        String password = mqttLoginDTO.getPassword();

        if(ObjectUtil.isNotEmpty(clientId) && ObjectUtil.isNotEmpty(username) && ObjectUtil.isNotEmpty(password)){
            Object clientIdObj = redisTemplate.opsForHash().get("mqtt_user:"+clientId,"clientId");
            Object usernameObj = redisTemplate.opsForHash().get("mqtt_user:"+clientId,"username");
            Object passwordObj = redisTemplate.opsForHash().get("mqtt_user:"+clientId,"password");
            if(clientIdObj != null && usernameObj != null && passwordObj != null){
                if(clientId.equals(clientIdObj.toString()) && username.equals(usernameObj.toString()) && password.equals(passwordObj.toString()) ){
                    return MqttLoginStatusEnum.ALLOW;
                }
            }
        }
        return MqttLoginStatusEnum.DENY;
    }

    // EMQX认证结果构造
    private Map<String, Object> constructMqttAuthResult(MqttLoginStatusEnum checkResult){
        Map<String, Object> responseBody = new HashMap<>();

        responseBody.put("is_superuser", false); // 是否超级用户
        responseBody.put("result", checkResult.getValue());

/*        // 设置客户端属性
        Map<String, String> clientAttrs = new HashMap<>();
        clientAttrs.put("role", "admin");
        clientAttrs.put("sn", "10c61f1a1f47");
        responseBody.put("client_attrs", clientAttrs);
        // 设置过期时间（Unix 时间戳，示例为未来的时间）
        responseBody.put("expire_at", System.currentTimeMillis() / 1000 + 3600); // 一小时后过期
        // 设置 ACL 权限
        List<Map<String, Object>> aclList = new ArrayList<>();
        responseBody.put("acl", aclList);*/

        return responseBody;
    }

    @Override
    public MqttAccountVO getMqttAccountByDevice(String device) {
        // 构造mqtt帐号
        MqttAccountVO mqttAccountVO = constructMqttAccount(device);
        // 插入redis
        insertMqttAccountToRedis(mqttAccountVO);
        return mqttAccountVO;
    }

    /*
    *   基于UUID生成mqtt的账号密码,device当做mqtt的clientId
    * */
    private MqttAccountVO constructMqttAccount(String device){
        String mqttUsername = UUID.randomUUID().toString().replace("-", "");
        String mqttPassword = UUID.randomUUID().toString().replace("-", "");

        MqttAccountVO mqttAccountVO = new MqttAccountVO();
        mqttAccountVO.setUsername(mqttUsername);
        mqttAccountVO.setPassword(mqttPassword);
        mqttAccountVO.setClientId(device);
        mqttAccountVO.setMqttUrl(mqttUrl);

        return mqttAccountVO;
    }

    private void insertMqttAccountToRedis(MqttAccountVO mqttAccountVO){
        // 如果该设备已经存在mqtt帐号，则删除原有的
        if(Boolean.TRUE.equals(redisTemplate.hasKey("mqtt_user:" + mqttAccountVO.getClientId()))){
            redisTemplate.delete("mqtt_user:"+mqttAccountVO.getClientId());
        }
        redisTemplate.boundHashOps("mqtt_user:"+mqttAccountVO.getClientId()).put("username",mqttAccountVO.getUsername());
        redisTemplate.boundHashOps("mqtt_user:"+mqttAccountVO.getClientId()).put("password",mqttAccountVO.getPassword());
        redisTemplate.boundHashOps("mqtt_user:"+mqttAccountVO.getClientId()).put("clientId",mqttAccountVO.getClientId());
    }

}
